import 'package:pp_uikit/pp_uikit_utils.dart';

class PPSelectionConstant {
  static const int maxSelectCount = 65535;
}

enum PPSelectionFilterType {
  /// 未设置
  none,

  /// 不限类型
  unLimit,

  /// 单选列表、单选项 type 为 radio
  radio,

  /// 多选列表、多选项 type 为 checkbox
  checkbox,

  /// 一般的值范围自定义区间 type 为 range
  range,

  /// 日期选择,普通筛选时使用 CalendarView 展示选择时间，更多情况下使用 DatePicker 选择时间
  date,

  /// 自定义选择日期区间， type 为 dateRange
  dateRange,

  /// 自定义通过 Calendar 选择日期区间，type 为 dateRangeCalendar
  dateRangeCalendar,

  /// 标签筛选 type 为 customerTag
  customHandle,

  /// 更多列表、多选项 无 type
  more,

  /// 去二级页面
  layer,

  /// 去自定义二级页面
  customLayer,
}

class PPSelectionEntity {
  /// 类型 是单选、复选还是有自定义输入
  late PPSelectionFilterType type;

  /// 回传给服务器的 key
  String? key;

  /// 回传给服务器的 value
  String? value;

  /// 默认值
  String? defaultValue;

  /// 显示的文案
  String title;

  /// 显示的文案
  String? subTitle;

  /// 扩展字段，目前只有min和max
  Map extMap;

  /// 子筛选项
  List<PPSelectionEntity> children;

  //////////// 以上为接口下发的原始数据字段 ///////////////

  //////////// 下方为组件另需要使用的字段 ///////////////
  /// 是否选中
  bool isSelected;

  /// 自定义输入
  Map<String, String>? customMap;

  /// 用于临时存储原有自定义字段数据，在筛选数据变化后未点击【确定】按钮时还原。
  late Map originalCustomMap;

  /// 最大可选数量
  int maxSelectedCount;

  /// 父级筛选项
  PPSelectionEntity? parent;

  /// 筛选类型，具体参见 [PPSelectionFilterType]
  late PPSelectionFilterType filterType;

  /// 筛选弹窗展示风格对应的首字母小写的字符串，例如 `range`、`list`，
  String? showType;

  /// 自定义标题
  String? customTitle;

  ///自定义筛选的 title 是否高亮
  bool isCustomTitleHighLight;

  /// 临时字段用于判断是否要将筛选项 [name] 字段拼接展示
  bool canJoinTitle = false;

  dynamic originData;

  PPSelectionEntity(
      {this.key,
      this.value,
      this.defaultValue,
      this.title = '',
      this.subTitle,
      this.children = const [],
      this.isSelected = false,
      this.extMap = const {},
      this.customMap,
      this.type = PPSelectionFilterType.none,
      this.showType,
      this.isCustomTitleHighLight = false,
      this.originData,
      this.maxSelectedCount = PPSelectionConstant.maxSelectCount}) {
    // filterType = parserFilterTypeWithType(type);
    filterType = PPSelectionFilterType.radio;
    // filterType = type;
    // this.filterShowType = parserShowType(this.showType);
    originalCustomMap = {};
  }

  /// 构造简单筛选数据
  PPSelectionEntity.simple({
    this.key,
    this.value,
    this.title = '',
    this.type = PPSelectionFilterType.none,
  })  : maxSelectedCount = PPSelectionConstant.maxSelectCount,
        isCustomTitleHighLight = false,
        isSelected = false,
        children = [],
        extMap = {} {
    // this.filterType = parserFilterTypeWithType(this.type);
    // this.filterShowType = parserShowType(this.showType);
    originalCustomMap = {};
    isSelected = false;
  }

  PPSelectionEntity.fromJson(Map<dynamic, dynamic>? map)
      : title = '',
        maxSelectedCount = PPSelectionConstant.maxSelectCount,
        isCustomTitleHighLight = false,
        isSelected = false,
        children = [],
        extMap = {} {
    if (map == null) return;
    title = map['title'] ?? '';
    subTitle = map['subTitle'] ?? '';
    key = map['key'] ?? '';
    type = map['type'] ?? '';
    defaultValue = map['defaultValue'] ?? '';
    value = map['value'] ?? '';
    if (map['maxSelectedCount'] != null &&
        int.tryParse(map['maxSelectedCount']) != null) {
      maxSelectedCount = int.tryParse(map['maxSelectedCount']) ??
          PPSelectionConstant.maxSelectCount;
    }
    extMap = map['ext'] ?? {};
    children = []..addAll(
        (map['children'] ?? []).map((o) => PPSelectionEntity.fromJson(o)));
    // filterType = parserFilterTypeWithType(map['type'] ?? '');
    isSelected = false;
  }

  void configRelationshipAndDefaultValue() {
    configRelationship();
    configDefaultValue();
  }

  void configRelationship() {
    if (children.isNotEmpty) {
      for (PPSelectionEntity entity in children) {
        entity.parent = this;
      }
      for (PPSelectionEntity entity in children) {
        entity.configRelationship();
      }
    }
  }

  void configDefaultValue() {
    if (children.isNotEmpty) {
      for (PPSelectionEntity entity in children) {
        if (!PPUIKitUtils.isEmpty(defaultValue)) {
          List<String> values = defaultValue!.split(',');
          entity.isSelected = values.contains(entity.value);
        }
      }

      for (PPSelectionEntity entity in children) {
        entity.configDefaultValue();
      }
      if (hasCheckBoxBrother()) {
        isSelected = children.where((_) => _.isSelected).isNotEmpty;
      } else {
        isSelected =
            isSelected || children.where((_) => _.isSelected).isNotEmpty;
      }
    }
  }

  PPSelectionFilterType parserFilterTypeWithType(String? type) {
    if (type == 'unlimit') {
      return PPSelectionFilterType.unLimit;
    } else if (type == "radio") {
      return PPSelectionFilterType.radio;
    } else if (type == "checkbox") {
      return PPSelectionFilterType.checkbox;
    } else if (type == "range") {
      return PPSelectionFilterType.range;
    } else if (type == "customHandle") {
      return PPSelectionFilterType.customHandle;
    } else if (type == "more") {
      return PPSelectionFilterType.more;
    } else if (type == 'floatinglayer') {
      return PPSelectionFilterType.layer;
    } else if (type == 'customfloatinglayer') {
      return PPSelectionFilterType.customLayer;
    } else if (type == 'date') {
      return PPSelectionFilterType.date;
    } else if (type == 'daterange') {
      return PPSelectionFilterType.dateRange;
    } else if (type == 'daterangecalendar') {
      return PPSelectionFilterType.dateRangeCalendar;
    }
    return PPSelectionFilterType.none;
  }

  void clearChildSelection() {
    if (children.isNotEmpty) {
      for (PPSelectionEntity entity in children) {
        entity.isSelected = false;

        entity.clearChildSelection();
      }
    }
  }

  /// 返回状态为选中的子节点
  static List<PPSelectionEntity> currentSelectListForEntity(
      PPSelectionEntity entity) {
    List<PPSelectionEntity> list = [];
    for (PPSelectionEntity entity in entity.children) {
      if (entity.isSelected) {
        list.add(entity);
      }
    }
    return list;
  }

  List<PPSelectionEntity> selectedLastColumnList() {
    List<PPSelectionEntity> list = [];
    if (this.children.isNotEmpty) {
      List<PPSelectionEntity> firstList = [];
      for (PPSelectionEntity firstEntity in this.children) {
        if (firstEntity.children.isNotEmpty) {
          List<PPSelectionEntity> secondList = [];
          for (PPSelectionEntity secondEntity in firstEntity.children) {
            if (secondEntity.children.isNotEmpty) {
              List<PPSelectionEntity> thirds =
                  currentSelectListForEntity(secondEntity);
              if (thirds.isNotEmpty) {
                list.addAll(thirds);
              } else if (secondEntity.isSelected) {
                secondList.add(secondEntity);
              }
            } else if (secondEntity.isSelected) {
              secondList.add(secondEntity);
            }
          }
          list.addAll(secondList);
        } else if (firstEntity.isSelected) {
          firstList.add(firstEntity);
        }
      }
      list.addAll(firstList);
    }
    return list;
  }

  List<PPSelectionEntity> selectedListWithoutUnlimit() {
    List<PPSelectionEntity> selected = selectedList();
    return selected.toList();
  }

  List<PPSelectionEntity> selectedList() {
    List<PPSelectionEntity> results = [];
    List<PPSelectionEntity> firstColumn = currentSelectListForEntity(this);
    results.addAll(firstColumn);
    if (firstColumn.isNotEmpty) {
      for (PPSelectionEntity firstEntity in firstColumn) {
        List<PPSelectionEntity> secondColumn =
            currentSelectListForEntity(firstEntity);
        results.addAll(secondColumn);
        if (secondColumn.isNotEmpty) {
          for (PPSelectionEntity secondEntity in secondColumn) {
            List<PPSelectionEntity> thirdColumn =
                currentSelectListForEntity(secondEntity);
            results.addAll(thirdColumn);
          }
        }
      }
    }
    return results;
  }

  List<PPSelectionEntity> allSelectedList() {
    List<PPSelectionEntity> results = [];
    List<PPSelectionEntity> firstColumn = currentSelectListForEntity(this);
    results.addAll(firstColumn);
    if (firstColumn.isNotEmpty) {
      for (PPSelectionEntity firstEntity in firstColumn) {
        List<PPSelectionEntity> secondColumn =
            currentSelectListForEntity(firstEntity);
        results.addAll(secondColumn);
        if (secondColumn.isNotEmpty) {
          for (PPSelectionEntity secondEntity in secondColumn) {
            List<PPSelectionEntity> thirdColumn =
                currentSelectListForEntity(secondEntity);
            results.addAll(thirdColumn);
          }
        }
      }
    }
    return results;
  }

  int getLimitedRootSelectedChildCount() {
    return getSelectedChildCount(getRootEntity(this));
  }

  int getLimitedRootMaxSelectedCount() {
    return getRootEntity(this).maxSelectedCount;
  }

  PPSelectionEntity getRootEntity(PPSelectionEntity rootEntity) {
    if (rootEntity.parent == null ||
        rootEntity.parent!.maxSelectedCount ==
            PPSelectionConstant.maxSelectCount) {
      return rootEntity;
    } else {
      return getRootEntity(rootEntity.parent!);
    }
  }

  /// 返回最后一层级【选中状态】 Item 的 个数
  int getSelectedChildCount(PPSelectionEntity entity) {
    if (PPUIKitUtils.isEmpty(entity.children)) {
      return entity.isSelected ? 1 : 0;
    }

    int count = 0;
    for (PPSelectionEntity child in entity.children) {
      count += getSelectedChildCount(child);
    }
    return count;
  }

  /// 判断当前的筛选 Item 是否为当前层次中第一个被选中的 Item。
  /// 用于展开筛选弹窗时显示选中效果。
  int getIndexInCurrentLevel() {
    if (parent == null || parent!.children.isEmpty) return -1;

    for (PPSelectionEntity entity in parent!.children) {
      if (entity == this) {
        return parent!.children.indexOf(entity);
      }
    }
    return -1;
  }

  /// 是否在筛选数据的最后一层。 如果最大层次为 3；某个筛选数据层次为 2，但其无子节点。此时认为不在最后一层。
  bool isInLastLevel() {
    if (parent == null || parent!.children.isEmpty) return true;

    for (PPSelectionEntity entity in parent!.children) {
      if (entity.children.isNotEmpty) {
        return false;
      }
    }
    return true;
  }

  /// 检查自己的兄弟结点是否存在 checkbox 类型。
  bool hasCheckBoxBrother() {
    int? count = parent?.children
        .where((f) => f.type == PPSelectionFilterType.checkbox)
        .length;
    return count == null ? false : count > 0;
  }

  /// 在这里简单认为 value 为空【null 或 ''】时为 unlimit.
  bool isUnLimit() {
    return filterType == PPSelectionFilterType.unLimit;
  }

  void clearSelectedEntity() {
    List<PPSelectionEntity> tmp = [];
    PPSelectionEntity node = this;
    tmp.add(node);
    while (tmp.isNotEmpty) {
      node = tmp.removeLast();
      node.isSelected = false;
      for (var data in node.children) {
        tmp.add(data);
      }
    }
  }

  List<PPSelectionEntity> currentTagListForEntity() {
    List<PPSelectionEntity> list = [];
    for (var data in children) {
      list.add(data);
    }
    return list;
  }

  List<PPSelectionEntity> currentShowTagByExpanded(bool isExpanded) {
    List<PPSelectionEntity> all = currentTagListForEntity();
    return isExpanded ? all : all.sublist(0, currentDefaultTagCountForEntity());
  }

  /// 最终显示tag个数
  int currentDefaultTagCountForEntity() {
    return currentTagListForEntity().length > getDefaultShowCount()
        ? getDefaultShowCount()
        : currentTagListForEntity().length;
  }

  /// 默认展示个数是否大于总tag个数
  bool isOverCurrentTagListSize() {
    return getDefaultShowCount() > currentTagListForEntity().length;
  }

  /// 接口返回默认展示tag个数
  int getDefaultShowCount() {
    int defaultShowCount = 3;
    if (extMap.containsKey('defaultShowCount')) {
      defaultShowCount = extMap['defaultShowCount'] ?? defaultShowCount;
    }
    return defaultShowCount;
  }

  List<PPSelectionEntity> currentRangeListForEntity() {
    List<PPSelectionEntity> list = [];
    for (var data in children) {
      list.add(data);
    }
    return list;
  }

  void reverseSelected() {
    isSelected = !isSelected;
  }

  int getFirstSelectedChildIndex() {
    return children.indexWhere((data) {
      return data.isSelected;
    });
  }

  @override
  bool operator ==(Object other) =>
      identical(this, other) ||
      other is PPSelectionEntity &&
          runtimeType == other.runtimeType &&
          key == other.key &&
          value == other.value &&
          defaultValue == other.defaultValue &&
          title == other.title &&
          children == other.children &&
          isSelected == other.isSelected &&
          extMap == other.extMap &&
          customMap == other.customMap &&
          type == other.type &&
          parent == other.parent
      // filterType == other.filterType
      ;

  @override
  int get hashCode =>
      key.hashCode ^
      value.hashCode ^
      defaultValue.hashCode ^
      title.hashCode ^
      children.hashCode ^
      isSelected.hashCode ^
      extMap.hashCode ^
      customMap.hashCode ^
      type.hashCode ^
      parent.hashCode
      // filterType.hashCode
      ;
}
